package com.fly.auth.user.service

import cn.hutool.core.bean.BeanUtil
import com.fly.auth.user.entity.User
import com.fly.auth.user.controller.repository.UserRepository
import com.fly.auth.user.pojo.UserDto
import com.fly.auth.user.pojo.toUser
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.reactive.asFlow
import kotlinx.coroutines.reactive.awaitFirstOrNull
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate
import org.springframework.data.r2dbc.query.Criteria.where
import org.springframework.data.relational.core.query.Query.query
import org.springframework.stereotype.Service

/**
 * @author  fly
 * @date  2021/5/21 14:18
 * @version 1.0
 */
@Service
class UserService(private val userRepository: UserRepository, private val r2dbcEntityTemplate: R2dbcEntityTemplate) {

    suspend fun findAll() = userRepository.findAll().asFlow()

    private suspend fun findById(id: Long) = userRepository.findById(id).awaitFirstOrNull()

    suspend fun findByName(name: String) = r2dbcEntityTemplate.select(User::class.java)
        .from("user")
        .matching(query(where("name").`is`(name))).all().asFlow()

    suspend fun findByEmail(email: String) = r2dbcEntityTemplate.select(User::class.java)
        .from("user").matching(query(where("email").`is`(email))).one().asFlow()

    suspend fun addUser(userDto: UserDto): Flow<User> {

        val user = User()
        BeanUtil.copyProperties(userDto, user)
        return userRepository.save(user).asFlow()
    }

    suspend fun updateUser(userDto: UserDto): User? = findById(userDto.id!!)?.run { userRepository.save(userDto.toUser())
        .awaitFirstOrNull()}

    suspend fun deleteUser(id: Long): Boolean = findById(id)?.run { userRepository.delete(this).awaitFirstOrNull()
    true } ?: false



}